﻿using Basic.FlowModel.AuditLog;
using Basic.FlowModel.AuditLogItem;
using Basic.FlowModel.AuditState;
using Basic.FlowRemoteModel;
using WeDonekRpc.Helper;

namespace Basic.FlowApplication.Model.AuditLog
{
    public class FlowAuditLogState
    {

        public FlowAuditLogState ( AuditLogDto log, AuditItemInfo[] items, AuditNodeState[] nodeState )
        {
            this.CurNodeState = nodeState.ToDictionary(c => c.NodeId, c => c.Status);
            this.Id = log.Id;
            this.CompanyId = log.CompanyId;
            this.FlowId = log.FlowId;
            this.AppId = log.AppId;
            this.AppType = log.AppType;
            this._ProgressVal = log.ProgressVal;
            this.BeginItemId = log.BeginItemId;
            this.LinkPk = log.LinkPk;
            this.LinkType = log.LinkType;
            this.Status = log.Status;
            this._AuditStatus = log.AuditStatus;
            this.DocTitle = log.DocTitle;
            this.EndTime = log.EndTime;
            this.CreateBy = log.CreateBy;
            this.CreateByDeptId = log.CreateByDeptId;
            this.CreateByUnitId = log.CreateByUnitId;
            this.LogItem = items.IsNull() ? new List<AfootAuditLogItem>() : items.Select(a => new AfootAuditLogItem(a, nodeState.Find(c => c.NodeId == a.NodeId, c => c.Status))).ToList();
            this._NodeState = new Dictionary<long, NodeState>();
            this.IsChange = false;
        }
        /// <summary>
        /// 日志ID
        /// </summary>
        public long Id
        {
            get;
        }
        /// <summary>
        /// 公司ID
        /// </summary>
        public long CompanyId
        {
            get;
        }
        /// <summary>
        /// 流程ID
        /// </summary>
        public long FlowId
        {
            get;
        }
        /// <summary>
        /// 应用ID
        /// </summary>
        public long AppId { get; }

        public FlowAppType AppType { get; }
        /// <summary>
        /// 进度值
        /// </summary>
        public bool ProgChange { get; private set; }

        private short _ProgressVal = 0;
        /// <summary>
        /// 进度值
        /// </summary>
        public short ProgressVal
        {
            get => this._ProgressVal;
            set
            {
                if ( this._ProgressVal != value )
                {
                    this._ProgressVal = value;
                    this.ProgChange = true;
                }
            }
        }
        /// <summary>
        /// 关联PK
        /// </summary>
        public long LinkPk { get; }

        /// <summary>
        /// 关联类型
        /// </summary>
        public string LinkType { get; }

        /// <summary>
        /// 文档标题
        /// </summary>
        public string DocTitle { get; }

        public long BeginItemId { get; }

        private FlowAuditStatus _AuditStatus;
        /// <summary>
        /// 审批状态
        /// </summary>
        public FlowAuditStatus AuditStatus
        {
            get => this._AuditStatus;
            set
            {
                if ( this._AuditStatus != value )
                {
                    this._AuditStatus = value;
                    if ( value == FlowAuditStatus.审核通过 || value == FlowAuditStatus.审核未通过 || value == FlowAuditStatus.已取消 || value == FlowAuditStatus.已关闭 )
                    {
                        this.Status = FlowAuditLogStatus.已结束;
                        this.EndTime = DateTime.Now;
                    }
                    else if ( value == FlowAuditStatus.审核进行中 )
                    {
                        this.Status = FlowAuditLogStatus.进行中;
                    }
                    this.IsChange = true;
                }
            }
        }
        /// <summary>
        /// 流程状态
        /// </summary>
        public FlowAuditLogStatus Status { get; private set; }

        /// <summary>
        /// 结束时间
        /// </summary>
        public DateTime? EndTime { get; private set; }

        public long? EndEmpId { get; set; }
        public long CreateBy { get; }

        public long CreateByUnitId { get; }

        public long CreateByDeptId { get; }
        /// <summary>
        /// 是否发生变更
        /// </summary>
        public bool IsChange { get; private set; } = false;
        public Dictionary<long, FlowNodeAuditStatus> CurNodeState { get; }
        private Dictionary<long, NodeState> _NodeState { get; }

        public void SyncNodeState ()
        {
            this.LogItem.ForEach(a =>
            {
                if ( a.ChangeType != LogItemChangeType.None && a.PrevNodeStatus != a.NodeStatus )
                {
                    this.SetNodeState(a.NodeId, a.NodeStatus, a.OptItemId.GetValueOrDefault(a.Id));
                }
            });
        }
        public Dictionary<long, NodeState> GetNodeState ()
        {
            this.SyncNodeState();
            return this._NodeState;
        }
        public void SetNodeState ( long nodeId, FlowNodeAuditStatus status, long optItemId, FlowNodeAuditStatus old )
        {
            FlowNodeAuditStatus prev = this.CurNodeState.GetValueOrDefault(nodeId, FlowNodeAuditStatus.待开始);
            if ( old == prev )
            {
                this._SetNodeState(nodeId, status, optItemId, prev);
            }
        }
        private void _SetNodeState ( long nodeId, FlowNodeAuditStatus status, long optItemId, FlowNodeAuditStatus prev )
        {
            if ( this._NodeState.ContainsKey(nodeId) )
            {
                return;
            }
            this.CurNodeState[nodeId] = status;
            this._NodeState.Add(nodeId, new NodeState
            {
                OptItemId = optItemId,
                Status = status,
                PrevStatus = prev,
            });
        }
        public void SetNodeState ( long nodeId, FlowNodeAuditStatus status, long optItemId )
        {
            FlowNodeAuditStatus prev = this.CurNodeState.GetValueOrDefault(nodeId, FlowNodeAuditStatus.待开始);
            this._SetNodeState(nodeId, status, optItemId, prev);
        }
        public List<AfootAuditLogItem> LogItem { get; private set; }
    }
}
